from prg.common.array_queue import ArrayQueue
from prg.udp_command_info import UdpCommandInfo
from prg.common.object_message import MessageBase


class LocalListen(MessageBase):
    def __init__(self, name, data_queue):
        super().__init__(name="local_listen_" + str(name))
        self.name_code = name
        self.send_queue = ArrayQueue()
        self.data_queue = data_queue
        self.max_data = 512
        self.socket_item = None
        self.local_addr = None
        self.data_num = 0

    def send_data(self, number, bytes_data):
        while number >= self.send_queue.last_index():
            self.send_queue.put(None, True)
        self.send_queue.set_value(number, bytes_data)
        try:
            bytes_item = self.send_queue.read()
            if bytes_item is None:
                return
            self.socket_item.send(bytes_item)
        except Exception as e:
            print("local send error: %s" % e)
        else:
            self.send_queue.get()

    def recv_data(self):
        with self.socket_item as socket_item:
            while self.is_run():
                try:
                    read_byte_tmp, read_addr_tmp = socket_item.recvfrom(self.max_data)
                except Exception as e:
                    print("local read error: %s" % e)
                    break
                else:
                    if len(read_byte_tmp) > 0:
                        udp_cmd = UdpCommandInfo(name=self.name_code, number=self.data_num, bytes_item=read_byte_tmp)
                        self.data_num += 1
                        self.data_queue.put(udp_cmd)

    def run_listen(self, socket_item):
        self.socket_item = socket_item
        self.local_addr = socket_item.getsockname()
        thr_recv = MessageBase(name="recv_listen", target=self.recv_data)
        thr_recv.start()
